package jmine.tec.rpc.common.serialization.json;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

import jmine.tec.json.JSON;
import jmine.tec.json.JSONArray;
import jmine.tec.json.JSONObject;
import jmine.tec.json.JSONString;

/**
 * Conversor de JSON para Java e vice-versa
 * 
 * @author lundberg
 */
public class JSONArrayConverter extends AbstractJSONObjectConverter<Object> {

    private static final String CLASS = "&componentType";

    private static final String VALUES = "&values";

    /**
     * {@inheritDoc}
     */
    public boolean matchesJava(Object object) {
        return object != null && object.getClass().isArray();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected JSON objectType() {
        return new JSONString("array");
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected Object instantiate(JSONConversionContext context, JSON json) {
        Class<?> componentType = (Class<?>) context.toJava(json.getProperty(CLASS));
        JSONArray jsonArray = (JSONArray) json.getProperty(VALUES);
        return Array.newInstance(componentType, jsonArray.getSize());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void fillObject(JSONConversionContext context, JSON json, Object object) {
        JSONArray jsonArray = (JSONArray) json.getProperty(VALUES);
        for (int i = 0; i < jsonArray.getSize(); i++) {
            Array.set(object, i, context.toJava(jsonArray.getProperty(i)));
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void fillJSON(JSONConversionContext context, Object object, JSONObject json) {
        json.setProperty(CLASS, context.toJSON(object.getClass().getComponentType()));
        List<JSON> elements = new ArrayList<JSON>(Array.getLength(object));
        for (int i = 0; i < Array.getLength(object); i++) {
            elements.add(context.toJSON(Array.get(object, i)));
        }
        json.setProperty(VALUES, new JSONArray(elements));
    }
}
